package network.server;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import network.protocol.Request;
import network.protocol.Response;

/**
 * RequestDispatcher 是请求分发器单例类，
 * 用于将客户端发送过来的请求分发给对应的 RequestHandler。
 *
 * 功能：
 * 1. 注册 action → handler 映射
 * 2. 统一处理请求（调用 handler）
 * 3. 将 requestId 添加到响应中
 */
public class RequestDispatcher {

    /** action 到 handler 的映射 */
    private static final Map<String, RequestHandler> handlerMap = new HashMap<>();
    private static final Logger logger = LoggerFactory.getLogger(RequestDispatcher.class);

    /** 单例实例 */
    private static final RequestDispatcher INSTANCE = new RequestDispatcher();

    /** 私有构造函数 */
    private RequestDispatcher() {
        logger.info("RequestDispatcher单例初始化");
    }

    /** 全局访问点 */
    public static RequestDispatcher getInstance() {
        return INSTANCE;
    }

    /**
     * 注册 handler
     *
     * @param action  请求动作名称
     * @param handler 对应的 RequestHandler
     */
    public void register(String action, RequestHandler handler) {
        handlerMap.put(action, handler);
    }

    /**
     * 统一处理请求
     *
     * @param req Request 对象
     * @return Response 响应对象
     */
    public Response<?> handle(Request req) {
        try {
            if (req == null || req.getAction() == null) {
                return Response.error(400, "请求格式错误或缺少 action");
            }

            logger.info("处理请求: {}, ID: {}中", req.getAction(), req.getRequestId());

            RequestHandler handler = handlerMap.get(req.getAction());
            if (handler == null) {
                return Response.error(404, "未找到对应的处理器: " + req.getAction());
            }

            // 打印请求参数
            Map<String,Object> mp = req.getParams();
            String requestKey = req.getRequestId();
            for(Map.Entry<String,Object> entry : mp.entrySet()){
                logger.info("参数 {}: {}", entry.getKey(), entry.getValue());
            }

            // 调用 handler 执行业务逻辑
            Response<?> response = handler.handle(req);
            logger.info("调用handler完毕");

            // 添加 requestId 到响应数据
            response = addRequestIdToResponse(response, requestKey);

            return response;

        } catch (Exception e) {
            logger.error("处理请求时发生错误: {}", e.getMessage(), e);
            return Response.error(500, "服务器错误: " + e.getMessage());
        }
    }

    /**
     * 将 requestId 添加到响应数据中
     *
     * @param response  原始响应
     * @param requestId 请求 ID
     * @return 包含 requestId 的 Response
     */
    private Response<?> addRequestIdToResponse(Response<?> response, String requestId) {
        if (response.getData() instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, Object> dataMap = (Map<String, Object>) response.getData();
            dataMap.put("requestId", requestId);
            logger.info(dataMap.toString());
            return response;
        } else {
            Map<String, Object> newData = new HashMap<>();
            newData.put("data", response.getData());
            newData.put("requestId", requestId);

            logger.info(newData.toString());

            Response<Map<String, Object>> newResponse = Response.success();
            newResponse.setCode(response.getCode());
            newResponse.setMsg(response.getMsg());
            newResponse.setData(newData);
            newResponse.setTimestamp(response.getTimestamp());

            return newResponse;
        }
    }
}
